/**
 *  TextMash - simple IDE for Clojure
 *  
 *  Copyright (C) 2010 Aleksander Naszko
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package pl.olek.textmash.workspace;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;

import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;

import pl.olek.textmash.Support;

/**
 * 
 * @author anaszko
 *
 */
public class LineNumbers extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3281334778590166380L;
	JTextPane pane;
	JScrollPane scrollPane;
	Color lineColor = new Color(230, 230, 230);
	Font lineFont = Support.getInstance().getFont();
	int width;
	
	public LineNumbers() {
		FontMetrics met = getFontMetrics(Support.getInstance().getFont());
		width = met.stringWidth("89745") + 3;
		setPreferredSize(new Dimension(width, width));
	}

	public void setObserver(JTextPane pane, JScrollPane scrollPane) {
		this.scrollPane = scrollPane;
		this.pane = pane;
		setBackground(pane.getBackground());
	}

	private int getLineAtCaret(JTextComponent component, Point p) {
		int caretPosition = component.viewToModel(p);
		Element root = component.getDocument().getDefaultRootElement();
		return root.getElementIndex(caretPosition) + 1;
	}

	public void paint(Graphics g) {
		super.paint(g);

		try {

			g.setColor(lineColor);
			g.drawLine(width - 1, 0, width - 1, pane.getHeight());

			g.setFont(lineFont);
			g.setColor(Color.GRAY);

			Point pstart = scrollPane.getViewport().getViewPosition();
			int start = pane.viewToModel(pstart);

			int pend_y = pstart.y + pane.getHeight();

			Font pfont = pane.getFont();
			FontMetrics pmet = g.getFontMetrics(pfont);

			int fontHeight = pmet.getHeight();
			int fontDesc = pmet.getDescent();
			int starting_y = -1;

			starting_y = pane.modelToView(start).y - pstart.y + fontHeight
					- fontDesc;

			int last = -1;
			for (int y = starting_y; pstart.y <= pend_y; y += fontHeight) {
				int pos = getLineAtCaret(pane, pstart);
				if (last != pos) {
					g.drawString(String.format("%4d", pos), 1, y);
				}
				last = pos;
				pstart.y += fontHeight;
			}

		} catch (Exception e1) {
			throw new RuntimeException(e1);
		}
	}
}
